package com.basker.pisces.springcloud.signature;

import java.security.SignatureException;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;

import com.basker.pisces.common.enums.SignatureAlgorithmType;
import com.basker.pisces.service.annotation.EnableSignValidation;
import com.basker.pisces.springcloud.GlobalAspect;
import com.basker.pisces.springcloud.utils.RequestUtils;
import com.basker.pisces.springcloud.utils.SignatureUtils;

/**
 * 拦截服务端响应，在执行前，从消息头中获取签名并校验，如果校验失败会返回异常
 *
 * @author hangwen
 */
@Aspect
public class SignatureValidateInterceptor extends GlobalAspect {

    @Autowired
    private SignatureValidator validator;

    /**
     * 满足切入点：方法需要签名 并且 当前类是restController，说明复合条件的是服务端，方法执行前需要对签名进行校验
     *
     * @param joinPoint
     * @param signValidation
     * @throws SignatureValidationException
     */
    @Before("@annotation(signValidation)&&restController()")
    public void validateSignature(JoinPoint joinPoint, EnableSignValidation signValidation) throws SignatureException {
        Signature postSignature = RequestUtils.getSignatureFromRequest();

        SignatureAlgorithmType signType = signValidation.signType();
        String appId = postSignature.getAppId();
        long timestamp = postSignature.getTimestamp();
        Object[] args = joinPoint.getArgs();
        Object bodyArg = args.length > 0 ? args[0] : null;

        Signature currentSignature = SignatureUtils.generateSignature(signType, appId, timestamp, bodyArg);

        this.validator.validate(currentSignature, postSignature, signValidation.timeoutMinutes());
    }

}
